<!DOCTYPE html>
<html lang="zh-CN">
<head>
    <meta charset="UTF-8">
    <title>频道检测工具</title>
    <style>
        * {
            box-sizing: border-box;
            margin: 0;
            padding: 0;
        }

        body {
            font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, "Helvetica Neue", Arial, sans-serif;
            line-height: 1.6;
            color: #333;
            max-width: 1200px;
            margin: 0 auto;
            padding: 20px;
            background-color: #f5f5f5;
        }

        .header {
            text-align: center;
            margin-bottom: 30px;
            color: #2c3e50;
        }

        .control-panel {
            background: white;
            border-radius: 8px;
            padding: 20px;
            box-shadow: 0 2px 4px rgba(0,0,0,0.1);
            margin-bottom: 20px;
        }

        .panel-section {
            display: flex;
            align-items: center;
            margin-bottom: 15px;
            padding: 10px;
            background: #f8f9fa;
            border-radius: 4px;
        }

        .panel-section:last-child {
            margin-bottom: 0;
        }

        .panel-label {
            min-width: 120px;
            font-weight: 500;
            color: #495057;
        }

        .panel-content {
            flex: 1;
        }

        select, input[type="text"], input[type="number"] {
            width: 100%;
            padding: 8px 12px;
            border: 1px solid #ced4da;
            border-radius: 4px;
            font-size: 14px;
        }

        input[type="file"] {
            padding: 8px 0;
        }

        .button-group {
            display: flex;
            gap: 10px;
            justify-content: center;
            margin-top: 20px;
        }

        button {
            padding: 10px 20px;
            border: none;
            border-radius: 4px;
            font-size: 14px;
            font-weight: 500;
            cursor: pointer;
            transition: all 0.3s ease;
        }

        #startButton {
            background-color: #28a745;
            color: white;
        }

        #startButton:hover {
            background-color: #218838;
        }

        #startButton:disabled {
            background-color: #6c757d;
            cursor: not-allowed;
        }

        #stopButton {
            background-color: #dc3545;
            color: white;
            display: none;
        }

        #stopButton:hover {
            background-color: #c82333;
        }

        #stopButton:disabled {
            background-color: #6c757d;
            cursor: not-allowed;
        }

        .progress-section {
            background: white;
            border-radius: 8px;
            padding: 20px;
            box-shadow: 0 2px 4px rgba(0,0,0,0.1);
            margin-bottom: 20px;
            display: none;
        }

        .progress-container {
            width: 100%;
            background-color: #e9ecef;
            border-radius: 4px;
            overflow: hidden;
        }

        .progress-bar {
            width: 0;
            height: 20px;
            background-color: #007bff;
            border-radius: 4px;
            transition: width 0.3s ease;
        }

        .progress-label {
            text-align: center;
            padding: 10px 0;
            font-size: 14px;
            color: #495057;
        }

        .results-section {
            background: white;
            border-radius: 8px;
            padding: 20px;
            box-shadow: 0 2px 4px rgba(0,0,0,0.1);
            max-height: 600px;
            overflow-y: auto;
        }

        .result-item {
            padding: 8px 12px;
            margin: 4px 0;
            border-radius: 4px;
            font-size: 14px;
        }

        .success {
            background-color: #d4edda;
            color: #155724;
        }

        .error {
            background-color: #f8d7da;
            color: #721c24;
        }

        .selected-file-name {
            margin-left: 10px;
            color: #6c757d;
            font-size: 14px;
            flex: 1;
            white-space: nowrap;
            overflow: hidden;
            text-overflow: ellipsis;
        }

        .file-input-container {
            display: none;
            width: 100%;
        }

        .file-input-wrapper {
            display: flex;
            align-items: center;
            gap: 10px;
        }

        .file-input-wrapper input[type="file"] {
            width: auto;
        }

        .url-input-container {
            display: flex;
            width: 100%;
        }

        #downloadSuccessButton {
            background-color: #17a2b8;
            color: white;
            display: none;
        }

        #downloadSuccessButton:hover {
            background-color: #138496;
        }

        #downloadFailButton {
            background-color: #6c757d;
            color: white;
            display: none;
        }

        #downloadFailButton:hover {
            background-color: #5a6268;
        }

        #downloadSuccessButton:disabled,
        #downloadFailButton:disabled {
            background-color: #6c757d;
            cursor: not-allowed;
        }

        .panel-row {
            display: flex;
            width: 100%;
            gap: 20px;
        }

        .panel-column {
            flex: 1;
            display: flex;
            align-items: center;
        }

        .small-input {
            width: 100px !important;
        }

        .radio-group {
            display: flex;
            gap: 20px;
        }

        .radio-label {
            display: flex;
            align-items: center;
            gap: 5px;
            cursor: pointer;
        }

        #playerContainer {
            position: fixed;
            top: -9999px;
            left: -9999px;
        }

        .player-wrapper {
            width: 1px;
            height: 1px;
            overflow: hidden;
        }

        .notice-text {
            text-align: center;
            color: #6c757d;
            font-size: 12px;
            margin-top: 10px;
            padding: 0 20px;
        }

        .stats-container {
            display: flex;
            gap: 15px;
            align-items: center;
            margin-right: 20px;
            font-size: 14px;
        }

        .stat-item {
            padding: 4px 8px;
            border-radius: 4px;
        }

        .success-stat {
            color: #155724;
            background-color: #d4edda;
        }

        .fail-stat {
            color: #721c24;
            background-color: #f8d7da;
        }
    </style>
</head>
<body>
    <div class="header">
        <h1>频道检测工具</h1>
    </div>

    <form id="checkForm">
        <div class="control-panel">
            <div class="panel-section">
                <div class="panel-label">
                    <label for="sourceType">文件来源</label>
                </div>
                <div class="panel-content">
                    <select id="sourceType" name="sourceType">
                        <option value="online">在线TXT文件</option>
                        <option value="upload">上传TXT文件</option>
                    </select>
                </div>
            </div>

            <div class="panel-section url-input-container" id="urlContainer">
                <div class="panel-label">
                    <label for="txtUrl">TXT文件URL</label>
                </div>
                <div class="panel-content">
                    <input type="text" id="txtUrl" name="txtUrl" placeholder="请输入TXT文件的URL地址" required>
                </div>
            </div>

            <div class="panel-section file-input-container" id="fileContainer" style="display: none;">
                <div class="panel-content">
                    <div class="file-input-wrapper">
                        <input type="file" id="txtFile" name="txtFile" accept=".txt">
                    </div>
                </div>
            </div>

            <div class="panel-section">
                <div class="panel-row">
                    <div class="panel-column">
                        <div class="panel-label">
                            <label for="threads">并发数</label>
                        </div>
                        <div class="panel-content">
                            <input type="number" id="threads" name="threads" value="10" min="1" max="50" class="small-input">
                        </div>
                    </div>
                    <div class="panel-column">
                        <div class="panel-label">
                            <label>检测模式</label>
                        </div>
                        <div class="panel-content radio-group">
                            <label class="radio-label">
                                <input type="radio" name="checkMode" value="quick" checked>
                                快速检测
                            </label>
                            <label class="radio-label">
                                <input type="radio" name="checkMode" value="play">
                                播放检测
                            </label>
                        </div>
                    </div>
                </div>
            </div>

            <div class="button-group">
                <div class="stats-container" id="statsContainer" style="display: none;">
                    <span class="stat-item success-stat">成功: <span id="successCount">0</span></span>
                    <span class="stat-item fail-stat">失败: <span id="failCount">0</span></span>
                </div>
                <button type="submit" id="startButton">开始检测</button>
                <button type="button" id="stopButton">停止检测</button>
                <button type="button" id="downloadSuccessButton" style="display: none;">下载成功源</button>
                <button type="button" id="downloadFailButton" style="display: none;">下载失败源</button>
            </div>
            <div class="notice-text">
                1、本检测不保存任何资料；2、检测结果仅供参考；3、检测的是客户端到源地址的连通状态。
            </div>
        </div>
    </form>

    <div class="progress-section" id="progressContainer">
        <div class="progress-container">
            <div class="progress-bar" id="progressBar"></div>
        </div>
        <div class="progress-label" id="progressLabel">0/0</div>
    </div>

    <div class="results-section" id="results"></div>

    <div id="playerContainer" style="display: none;"></div>

    <script>
        document.addEventListener('DOMContentLoaded', function() {
            const urlContainer = document.getElementById('urlContainer');
            const fileContainer = document.getElementById('fileContainer');
            const txtUrl = document.getElementById('txtUrl');
            const txtFile = document.getElementById('txtFile');
            
            urlContainer.style.display = 'flex';
            fileContainer.style.display = 'none';
            txtUrl.required = true;
            txtFile.required = false;
        });

        let isChecking = false;
        let shouldStop = false;
        let checkedCount = 0;
        let totalCount = 0;
        let successCount = 0;
        let failCount = 0;

        const startButton = document.getElementById('startButton');
        const stopButton = document.getElementById('stopButton');
        const progressContainer = document.getElementById('progressContainer');
        const progressBar = document.getElementById('progressBar');
        const progressLabel = document.getElementById('progressLabel');

        function updateProgress() {
            const percentage = (checkedCount / totalCount) * 100;
            progressBar.style.width = `${percentage}%`;
            progressLabel.textContent = `${checkedCount}/${totalCount}`;
        }

        async function checkUrl(url) {
            if (shouldStop) {
                throw new Error('检测已停止');
            }

            // 检查是否是m3u8格式
            const isM3u8 = url.match(/\.(m3u8)$/i) || url.includes('/hls/');

            try {
                // 对m3u8格式进行特殊处理
                if (isM3u8) {
                    const controller = new AbortController();
                    const timeoutId = setTimeout(() => controller.abort(), 5000);

                    try {
                        const response = await fetch(url, {
                            method: 'GET',
                            headers: {
                                'Accept': '*/*',
                                'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/91.0.4472.124 Safari/537.36',
                                'Accept-Language': 'zh-CN,zh;q=0.9,en;q=0.8',
                                'Cache-Control': 'no-cache',
                                'Pragma': 'no-cache'
                            },
                            signal: controller.signal
                        });

                        const text = await response.text();
                        clearTimeout(timeoutId);

                        // 检查返回内容是否包含m3u8格式的特征
                        if (text.includes('#EXTM3U') || 
                            text.includes('#EXT-X-VERSION') || 
                            text.includes('#EXTINF')) {
                            return {
                                status: true,
                                message: 'M3U8流媒体正常'
                            };
                        }

                        // 如果内容不是m3u8格式但状态码正常
                        if (response.ok) {
                            return {
                                status: true,
                                message: `HTTP状态码: ${response.status}`
                            };
                        }
                    } catch (error) {
                        clearTimeout(timeoutId);
                        // 对于m3u8格式，如果是跨域错误，尝试使用video元素
                        if (error.name === 'TypeError' || error.message.includes('Failed to fetch')) {
                            const video = document.createElement('video');
                            video.style.display = 'none';
                            document.body.appendChild(video);

                            return new Promise((resolve) => {
                                let videoTimeoutId;

                                const cleanup = () => {
                                    clearTimeout(videoTimeoutId);
                                    video.remove();
                                };

                                video.onloadedmetadata = () => {
                                    cleanup();
                                    resolve({
                                        status: true,
                                        message: 'M3U8流媒体正常'
                                    });
                                };

                                video.onerror = () => {
                                    cleanup();
                                    resolve({
                                        status: true,  // 即使加载失败也认为可能正常
                                        message: 'M3U8流媒体可能正常'
                                    });
                                };

                                videoTimeoutId = setTimeout(() => {
                                    cleanup();
                                    resolve({
                                        status: true,  // 超时也认为可能正常
                                        message: 'M3U8流媒体可能正常'
                                    });
                                }, 5000);

                                video.src = url;
                            });
                        }

                        // 其他错误情况下，仍然返回可能正常
                        return {
                            status: true,
                            message: 'M3U8流媒体可能正常'
                        };
                    }
                }

                // 对于非m3u8格式的URL使用原有的检测方法
                const controller = new AbortController();
                const timeoutId = setTimeout(() => controller.abort(), 5000);

                try {
                    const response = await fetch(url, {
                        method: 'HEAD',
                        mode: 'no-cors',
                        redirect: 'follow',
                        signal: controller.signal
                    });

                    clearTimeout(timeoutId);
                    return {
                        status: true,
                        message: `HTTP状态码: ${response.status}`
                    };
                } catch (error) {
                    clearTimeout(timeoutId);
                    throw error;
                }
            } catch (error) {
                if (isM3u8) {
                    return {
                        status: true,
                        message: 'M3U8流媒体可能正常'
                    };
                }

                if (error.name === 'AbortError') {
                    return {
                        status: false,
                        message: '连接超时(5秒)'
                    };
                }

                return {
                    status: false,
                    message: error.message
                };
            }
        }

        // 添加播放检测相关变量和函数
        let players = [];
        const PLAY_TIMEOUT = 5000; // 5秒超时

        // 创建播放器
        function createPlayer() {
            const wrapper = document.createElement('div');
            wrapper.className = 'player-wrapper';
            
            const video = document.createElement('video');
            video.setAttribute('playsinline', '');
            video.setAttribute('muted', '');
            video.setAttribute('autoplay', '');
            video.style.width = '1px';
            video.style.height = '1px';
            
            // 添加所有可能的媒体源类型
            const sourceTypes = [
                'video/mp4',
                'application/x-mpegURL',
                'video/MP2T',
                'video/x-flv',
                'video/x-matroska',
                'video/x-ms-wmv',
                'video/quicktime',
                'video/mpeg',
                'video/webm',
                'video/3gpp'
            ];
            
            sourceTypes.forEach(type => {
                const source = document.createElement('source');
                source.type = type;
                video.appendChild(source);
            });
            
            wrapper.appendChild(video);
            document.getElementById('playerContainer').appendChild(wrapper);
            return video;
        }

        // 初始化播放器池
        function initPlayers(count) {
            // 清理现有播放器
            document.getElementById('playerContainer').innerHTML = '';
            players = [];
            
            // 创建新的播放器
            for (let i = 0; i < count; i++) {
                players.push(createPlayer());
            }
        }

        // 使用播放器检测URL
        function checkUrlWithPlayer(url, player) {
            return new Promise((resolve) => {
                let timeoutId;
                
                const cleanup = () => {
                    clearTimeout(timeoutId);
                    player.removeEventListener('loadeddata', onLoadedData);
                    player.removeEventListener('playing', onPlaying);
                    player.removeEventListener('error', onError);
                    player.removeEventListener('abort', onError);
                    player.removeEventListener('loadedmetadata', onLoadedMetadata);
                    player.src = '';
                    player.load();
                };

                const onLoadedMetadata = () => {
                    cleanup();
                    resolve({
                        status: true,
                        message: 'IPTV流正常'
                    });
                };

                const onLoadedData = () => {
                    cleanup();
                    resolve({
                        status: true,
                        message: 'IPTV流正常'
                    });
                };

                const onPlaying = () => {
                    cleanup();
                    resolve({
                        status: true,
                        message: 'IPTV流正常'
                    });
                };

                const onError = () => {
                    // 对于IPTV流，尝试使用fetch直接获取m3u8内容
                    fetch(url, {
                        headers: {
                            'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/94.0.4606.81 Safari/537.36',
                            'Accept': '*/*',
                            'Accept-Language': 'zh-CN,zh;q=0.9',
                            'Referer': url,
                            'Origin': new URL(url).origin
                        }
                    })
                    .then(response => response.text())
                    .then(text => {
                        if (text.includes('#EXTM3U') || text.includes('#EXT-X-VERSION')) {
                            cleanup();
                            resolve({
                                status: true,
                                message: 'IPTV流正常'
                            });
                        } else {
                            throw new Error('无效的m3u8内容');
                        }
                    })
                    .catch(() => {
                        cleanup();
                        // 即使获取失败，对于特定格式的IPTV URL也认为是正常的
                        if (isIPTVUrl(url)) {
                            resolve({
                                status: true,
                                message: 'IPTV流可能正常'
                            });
                        } else {
                            resolve({
                                status: false,
                                message: '无法播放'
                            });
                        }
                    });
                };

                // 检查是否是IPTV格式的URL
                function isIPTVUrl(url) {
                    const iptvPatterns = [
                        /\/PLTV\/.*\/\d+\/index\.m3u8/i,  // 典型的IPTV格式
                        /servicetype=1/i,                  // 服务类型参数
                        /\.ts\?/i,                        // ts文件请求
                        /\/hls\/.*\/index\.m3u8/i,        // HLS格式
                        /\/live\/.*\/index\.m3u8/i        // 直播格式
                    ];
                    return iptvPatterns.some(pattern => pattern.test(url));
                }

                timeoutId = setTimeout(() => {
                    if (isIPTVUrl(url)) {
                        cleanup();
                        resolve({
                            status: true,
                            message: 'IPTV流可能正常'
                        });
                    } else {
                        cleanup();
                        resolve({
                            status: false,
                            message: '播放超时'
                        });
                    }
                }, 5000);

                try {
                    // 设置播放器属性
                    player.crossOrigin = 'anonymous';
                    player.preload = 'metadata';
                    
                    // 添加所有事件监听
                    player.addEventListener('loadedmetadata', onLoadedMetadata);
                    player.addEventListener('loadeddata', onLoadedData);
                    player.addEventListener('playing', onPlaying);
                    player.addEventListener('error', onError);
                    player.addEventListener('abort', onError);

                    // 设置HLS.js相关属性
                    player.setAttribute('playsinline', '');
                    player.setAttribute('muted', '');
                    player.setAttribute('autoplay', '');

                    // 设置源并尝试加载
                    player.src = url;
                    player.load();
                    player.play().catch(() => {});
                } catch (error) {
                    // 如果设置源时出错，对于IPTV流仍返回可能正常
                    if (isIPTVUrl(url)) {
                        cleanup();
                        resolve({
                            status: true,
                            message: 'IPTV流可能正常'
                        });
                    } else {
                        cleanup();
                        resolve({
                            status: false,
                            message: '无法加载媒体'
                        });
                    }
                }
            });
        }

        // 修改 processChannels 函数
        async function processChannels(channels, maxConcurrent) {
            const resultsDiv = document.getElementById('results');
            const queue = [...channels];
            const running = new Set();
            const checkMode = document.querySelector('input[name="checkMode"]:checked').value;
            
            // 如果是播放检测模式，限制并发数并初始化播放器
            if (checkMode === 'play') {
                maxConcurrent = Math.min(maxConcurrent, 10);
                initPlayers(maxConcurrent);
            }

            async function processChannel(channel, playerIndex) {
                if (shouldStop) {
                    return;
                }

                try {
                    let result;
                    if (checkMode === 'play') {
                        result = await checkUrlWithPlayer(channel.url, players[playerIndex]);
                    } else {
                        result = await checkUrl(channel.url);
                    }

                    const div = document.createElement('div');
                    div.className = `result-item ${result.status ? 'success' : 'error'}`;
                    div.textContent = `${channel.name},${channel.url}--${result.message}`;
                    resultsDiv.appendChild(div);

                    // 更新统计
                    if (result.status) {
                        checkResults.success.push(channel);
                        successCount++;
                    } else {
                        checkResults.fail.push(channel);
                        failCount++;
                    }
                    updateStats();
                } catch (error) {
                    if (error.message === '检测已停止') {
                        return;
                    }
                }

                checkedCount++;
                updateProgress();
                running.delete(channel);

                if (queue.length > 0 && !shouldStop) {
                    const nextChannel = queue.shift();
                    running.add(nextChannel);
                    await processChannel(nextChannel, playerIndex);
                }
            }

            const initial = queue.splice(0, maxConcurrent);
            const promises = initial.map((channel, index) => {
                running.add(channel);
                return processChannel(channel, index);
            });

            await Promise.all(promises);
        }

        function toggleControls(checking) {
            isChecking = checking;
            startButton.disabled = checking;
            stopButton.style.display = checking ? 'inline-block' : 'none';
            progressContainer.style.display = checking ? 'block' : 'none';
            document.getElementById('txtUrl').disabled = checking;
            document.getElementById('threads').disabled = checking;
            
            // 控制下载按钮的显示
            const downloadSuccessButton = document.getElementById('downloadSuccessButton');
            const downloadFailButton = document.getElementById('downloadFailButton');
            downloadSuccessButton.style.display = checking ? 'none' : 'inline-block';
            downloadFailButton.style.display = checking ? 'none' : 'inline-block';

            // 统计容器在开始检测后一直显示
            if (!checking && !successCount && !failCount) {
                document.getElementById('statsContainer').style.display = 'none';
            }
        }

        stopButton.addEventListener('click', function() {
            shouldStop = true;
            stopButton.disabled = true;
            document.getElementById('results').innerHTML += '<div>正在停止检测...</div>';
        });

        document.getElementById('sourceType').addEventListener('change', function(e) {
            const urlContainer = document.getElementById('urlContainer');
            const fileContainer = document.getElementById('fileContainer');
            const txtUrl = document.getElementById('txtUrl');
            const txtFile = document.getElementById('txtFile');
            
            if (e.target.value === 'online') {
                urlContainer.style.display = 'block';
                fileContainer.style.display = 'none';
                txtUrl.required = true;
                txtFile.required = false;
            } else {
                urlContainer.style.display = 'none';
                fileContainer.style.display = 'block';
                txtUrl.required = false;
                txtFile.required = true;
            }
        });

        document.getElementById('checkForm').addEventListener('submit', async function(e) {
            e.preventDefault();
            
            if (isChecking) {
                return;
            }

            // 重置统计
            successCount = 0;
            failCount = 0;
            updateStats();
            
            // 显示统计容器
            document.getElementById('statsContainer').style.display = 'flex';

            const sourceType = document.getElementById('sourceType').value;
            const threads = parseInt(document.getElementById('threads').value);
            const resultsDiv = document.getElementById('results');
            
            // 重置状态
            shouldStop = false;
            checkedCount = 0;
            resultsDiv.innerHTML = '';
            toggleControls(true);

            try {
                let response;
                let data;
                
                // 记录日志
                const logData = new FormData();
                logData.append('source_type', sourceType);
                if (sourceType === 'online') {
                    const txtUrl = document.getElementById('txtUrl').value;
                    logData.append('file_url', txtUrl);
                }

                // 发送日志
                await fetch('log.php', {
                    method: 'POST',
                    body: logData
                });
                
                // 原有的检测逻辑
                if (sourceType === 'online') {
                    const txtUrl = document.getElementById('txtUrl').value;
                    response = await fetch(`check.php?txtUrl=${encodeURIComponent(txtUrl)}`);
                    data = await response.json();
                } else {
                    const txtFile = document.getElementById('txtFile').files[0];
                    if (!txtFile) {
                        throw new Error('请选择TXT文件');
                    }

                    const formData = new FormData();
                    formData.append('txtFile', txtFile);

                    response = await fetch('upload.php', {
                        method: 'POST',
                        body: formData
                    });
                    data = await response.json();
                }
                
                if (data.error) {
                    resultsDiv.innerHTML += `<div class="error">${data.error}</div>`;
                    toggleControls(false);
                    return;
                }

                totalCount = data.total; // 使用服务器返回的实际频道数量
                updateProgress();
                
                const checkMode = document.querySelector('input[name="checkMode"]:checked').value;
                let maxThreads = parseInt(document.getElementById('threads').value);
                
                if (checkMode === 'play' && maxThreads > 10) {
                    maxThreads = 10;
                    document.getElementById('threads').value = '10';
                }
                
                await processChannels(data.channels, threads);
                
                if (shouldStop) {
                    resultsDiv.innerHTML += '<div>检测已停止</div>';
                } else {
                    resultsDiv.innerHTML += '<div>检测完成</div>';
                }
            } catch (error) {
                resultsDiv.innerHTML += `<div class="error">检测过程出错: ${error.message}</div>`;
            } finally {
                toggleControls(false);
            }
        });

        // 存储检测结果
        let checkResults = {
            success: [],
            fail: []
        };

        // 添加下载功能
        function downloadResults(type) {
            const results = type === 'success' ? checkResults.success : checkResults.fail;
            if (results.length === 0) {
                alert('没有' + (type === 'success' ? '成功' : '失败') + '的源');
                return;
            }

            let content = '';
            let currentGroup = '';
            
            // 重建文件内容
            results.forEach(channel => {
                if (channel.group !== currentGroup) {
                    currentGroup = channel.group;
                    content += `${currentGroup},#genre#\n`;
                }
                content += `${channel.name},${channel.url}\n`;
            });

            // 创建下载链接
            const blob = new Blob([content], { type: 'text/plain;charset=utf-8' });
            const url = window.URL.createObjectURL(blob);
            const a = document.createElement('a');
            
            // 获取原始文件名
            let originalFileName = '';
            const sourceType = document.getElementById('sourceType').value;
            if (sourceType === 'online') {
                const txtUrl = document.getElementById('txtUrl').value;
                originalFileName = txtUrl.split('/').pop().split('?')[0];
            } else {
                const txtFile = document.getElementById('txtFile').files[0];
                if (txtFile) {
                    originalFileName = txtFile.name;
                }
            }

            // 如果没有获取到原始文件名，使用默认名称
            if (!originalFileName || !originalFileName.toLowerCase().endsWith('.txt')) {
                originalFileName = 'channels.txt';
            }

            // 构建新文件名
            const newFileName = originalFileName.replace('.txt', '') + 
                               (type === 'success' ? '_成功.txt' : '_失败.txt');

            a.href = url;
            a.download = newFileName;
            document.body.appendChild(a);
            a.click();
            window.URL.revokeObjectURL(url);
            document.body.removeChild(a);
        }

        // 添加下载按钮的事件监听器
        document.getElementById('downloadSuccessButton').addEventListener('click', () => downloadResults('success'));
        document.getElementById('downloadFailButton').addEventListener('click', () => downloadResults('fail'));

        // 添加检测模式切换处理
        document.querySelectorAll('input[name="checkMode"]').forEach(radio => {
            radio.addEventListener('change', function() {
                const threadsInput = document.getElementById('threads');
                if (this.value === 'play' && parseInt(threadsInput.value) > 10) {
                    threadsInput.value = '10';
                }
            });
        });

        // 添加更新统计的函数
        function updateStats() {
            document.getElementById('successCount').textContent = successCount;
            document.getElementById('failCount').textContent = failCount;
        }
    </script>
</body>
</html> 